package org.jeecg.modules.finance.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.cmbCloudDirectLink.utils.CMBApi;
import org.jeecg.common.api.dto.BankSetDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.LimitSubmit;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.business.service.ICaishuiBusinessService;
import org.jeecg.modules.business.service.ICaishuiCompanySetService;
import org.jeecg.modules.finance.mapper.CaishuiRechargeMapper;
import org.jeecg.modules.finance.service.ICaishuiBillService;
import org.jeecg.modules.finance.service.ICaishuiRefundRecordService;
import org.jeecg.modules.manage.entity.*;
import org.jeecg.modules.settle.service.ICaishuiTaskSettleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 退款记录[B端]
 * @Author: yfkj
 * @Date: 2023-04-10
 * @Version: V1.0
 */
@Api(tags = "退款记录[B端]")
@RestController
@RequestMapping("/finance/caishuiRefundRecord")
@Slf4j
public class CaishuiRefundRecordController extends JeecgController<CaishuiRefundRecord, ICaishuiRefundRecordService> {

    @Autowired
    private ICaishuiRefundRecordService iCaishuiRefundRecordService;
    @Autowired
    private ICaishuiBusinessService iCaishuiBusinessService;
    @Autowired
    private ICaishuiCompanySetService iCaishuiCompanySetService;
    @Autowired
    private ICaishuiBillService iCaishuiBillService;
    @Autowired
    private ICaishuiTaskSettleService iCaishuiTaskSettleService;
    @Resource
    private ISysBaseAPI iSysBaseAPI;
    @Resource
    private CaishuiRechargeMapper caishuiRechargeMapper;
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 分页列表查询
     *
     * @param caishuiRefundRecord
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "退款记录[B端]-分页列表查询", notes = "退款记录[B端]-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<CaishuiRefundRecord>> queryPageList(CaishuiRefundRecord caishuiRefundRecord,
                                                            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                            HttpServletRequest req) {
        QueryWrapper<CaishuiRefundRecord> queryWrapper = QueryGenerator.initQueryWrapper(caishuiRefundRecord, req.getParameterMap());
        queryWrapper.lambda().eq(CaishuiRefundRecord::getBusinessId, TokenUtils.getLoginUser().getCurBusiness());
        queryWrapper.lambda().eq(CaishuiRefundRecord::getCompanyId, TokenUtils.getLoginUser().getCurCompany());
        Page<CaishuiRefundRecord> page = new Page<CaishuiRefundRecord>(pageNo, pageSize);
        IPage<CaishuiRefundRecord> pageList = iCaishuiRefundRecordService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 查询商户银行信息
     *
     * @return
     */
    @ApiOperation(value = "退款记录[B端]-查询商户银行信息", notes = "退款记录[B端]-查询商户银行信息")
    @GetMapping(value = "/queryBusinessBankInfo")
    public Result<?> queryBusinessBankInfo() {
        JSONObject result = new JSONObject(9);
        //当前登录用户
        LoginUser loginUser = TokenUtils.getLoginUser();
        //查询当前登录商户银行信息
        Map<String, String> param = new HashMap<>();
        param.put("businessId", loginUser.getCurBusiness());
        param.put("companyId", loginUser.getCurCompany());
        CaishuiBusinessBank businessBank = iCaishuiBusinessService.queryBusinessBank(param);
        if (oConvertUtils.isEmpty(businessBank)) return Result.error("商户银行信息不存在！");
        //账户余额
        double accountBalance = 0.00;
        BankSetDTO bankSetDTO = iCaishuiCompanySetService.queryCompanySet(businessBank.getMainAccount());
        Result b_result = CMBApi.querySubUnitBalance(businessBank.getMainAccount(),businessBank.getSubAccountId(), bankSetDTO);
        if(b_result.isSuccess()){
            accountBalance = oConvertUtils.getDouble(b_result.getResult().toString(),0.00);
        }
        result.put("accountBalance", accountBalance);

        //充值总额
        param.put("status","1");
        Map<String,Object> map = caishuiRechargeMapper.queryTotalAmount(param);
        double rechargeTotalAmount = oConvertUtils.getDouble(map.get("amount")+"",0.00);

        double refundableAmount = 0.00;//可退款金额
        if(rechargeTotalAmount > 0){
            //开票金额（开票中+开票成功）
            param.put("status","");
            param.put("inStatus","0,1,2,7");
            double billAmount = iCaishuiBillService.queryBillTotal(param);
            //退款金额（退款中+退款成功）
            param.put("status","");
            param.put("inStatus","0,1,3,4");
            map = iCaishuiRefundRecordService.queryRefundTotal(param);
            double refundAmount = oConvertUtils.getDouble(map.get("money")+"",0.00);
            //可退款金额 = 充值总额 - 开票金额（开票中+开票成功） - 退款金额（退款中+退款成功）
            refundableAmount = BigDecimal.valueOf(rechargeTotalAmount).subtract(BigDecimal.valueOf(billAmount)).subtract(BigDecimal.valueOf(refundAmount)).setScale(BigDecimal.ROUND_HALF_UP).doubleValue();
            if (refundableAmount < 0) refundableAmount = 0.00;
            if (refundableAmount > accountBalance) refundableAmount = accountBalance;//如果可退款金额>账户余额，则只能退款当前可用余额
        }
        result.put("refundableAmount", refundableAmount);

        //返回结果
        result.put("tenantId", businessBank.getTenantId());
		result.put("payAccount", businessBank.getMainAccount());
		result.put("payName", businessBank.getName());
		result.put("payDmanbr", businessBank.getSubAccountId());
		result.put("payDmanam", businessBank.getAccountName());
		result.put("crtAccountList", caishuiRechargeMapper.queryRechargePayInfo(param));
        return Result.OK(result);
    }

    /**
     * 添加
     *
     * @param caishuiRefundRecord
     * @return
     */
    @AutoLog(value = "退款记录[B端]-添加")
    @ApiOperation(value = "退款记录[B端]-添加", notes = "退款记录[B端]-添加")
    @PostMapping(value = "/add")
    @LimitSubmit(key = "business:refund:add:%bId:%cId")
    public Result<String> add(@RequestBody CaishuiRefundRecord caishuiRefundRecord) {
        //当前登录用户
        LoginUser loginUser = TokenUtils.getLoginUser();
        double fee = 0.00;//手续费
        if (caishuiRefundRecord.getMoney() <= 5) {
            return Result.error("退款金额不能小于等于5元！");
        } else if (caishuiRefundRecord.getMoney() <= 10000) {
            fee = 5.00;
        } else if (caishuiRefundRecord.getMoney() <= 100000) {
            fee = 10.00;
        } else if (caishuiRefundRecord.getMoney() <= 500000) {
            fee = 15.00;
        } else if (caishuiRefundRecord.getMoney() <= 1000000) {
            fee = 20.00;
        } else {
            return Result.error("退款金额不能大于100万元！");
        }

        //判断是否存在退款中的数据
        CaishuiRefundRecord refundRecord = iCaishuiRefundRecordService.getOne(new LambdaQueryWrapper<CaishuiRefundRecord>()
                .select(CaishuiRefundRecord::getStatus).eq(CaishuiRefundRecord::getBusinessId,loginUser.getCurBusiness())
                .eq(CaishuiRefundRecord::getCompanyId,loginUser.getCurCompany()).orderByDesc(CaishuiRefundRecord::getCreateTime)
                .last("LIMIT 1"));
        if (oConvertUtils.isNotEmpty(refundRecord) && oConvertUtils.isNotEmpty(refundRecord.getStatus())){
            if (refundRecord.getStatus()==0) return Result.error("请先操作完成上一笔【退款】订单！");
            if (refundRecord.getStatus()==1) return Result.error("请先处理完成上一笔【退款】订单！");
            if (refundRecord.getStatus()==3) return Result.error("请耐心等待上一笔【退款】订单银行处理完成！");
        }

        //判断是否存在发放中的数据
        CaishuiTaskSettle taskSettle = iCaishuiTaskSettleService.getOne(new LambdaQueryWrapper<CaishuiTaskSettle>()
                .select(CaishuiTaskSettle::getStatus,CaishuiTaskSettle::getExtendStatus)
                .eq(CaishuiTaskSettle::getBusinessId,loginUser.getCurBusiness()).eq(CaishuiTaskSettle::getCompanyId,loginUser.getCurCompany())
                .orderByDesc(CaishuiTaskSettle::getCreateTime).last("LIMIT 1"));
        if (oConvertUtils.isNotEmpty(taskSettle) && oConvertUtils.isNotEmpty(taskSettle.getStatus())
                && oConvertUtils.isNotEmpty(taskSettle.getExtendStatus())){
            if (taskSettle.getStatus()==0) return Result.error("请先操作完成上一笔【任务结算】订单！");
            if (taskSettle.getStatus()==1) return Result.error("请耐心等待上一笔【任务结算】订单审核完成！");
            if (taskSettle.getStatus()==2) {
                if (taskSettle.getExtendStatus()==0 || taskSettle.getExtendStatus()==1
                        || taskSettle.getExtendStatus()==4) {
                    return Result.error("请耐心等待上一笔【任务结算】订单银行处理完成！");
                }
            }
        }

        //判断是否存在开票中的数据
        CaishuiBill bill = iCaishuiBillService.getOne(new LambdaQueryWrapper<CaishuiBill>()
                .select(CaishuiBill::getStatus).eq(CaishuiBill::getBusinessId,loginUser.getCurBusiness())
                .eq(CaishuiBill::getCompanyId,loginUser.getCurCompany()).orderByDesc(CaishuiBill::getCreateTime)
                .last("LIMIT 1"));
        if (oConvertUtils.isNotEmpty(bill) && oConvertUtils.isNotEmpty(bill.getStatus())){
            if (bill.getStatus()==0) return Result.error("请先操作完成上一笔【开票】信息！");
            if (bill.getStatus()==1) return Result.error("请耐心等待上一笔【开票】信息审核完成！");
            if (bill.getStatus()==2) return Result.error("请耐心等待上一笔【开票】信息处理完成！");
        }

        //账户余额
        double accountBalance = 0.00;
        BankSetDTO bankSetDTO = iCaishuiCompanySetService.queryCompanySet(caishuiRefundRecord.getPayAccount());
        Result b_result = CMBApi.querySubUnitBalance(caishuiRefundRecord.getPayAccount(),caishuiRefundRecord.getPayDmanbr(), bankSetDTO);
        if(b_result.isSuccess()){
            accountBalance = oConvertUtils.getDouble(b_result.getResult().toString(),0.00);
        }
        if (caishuiRefundRecord.getMoney() > accountBalance) return Result.error("账户余额不足！");

        //充值总额
        Map<String, String> params = new HashMap<>();
        params.put("businessId", loginUser.getCurBusiness());
        params.put("companyId", loginUser.getCurCompany());
        params.put("status","1");
        Map<String,Object> map = caishuiRechargeMapper.queryTotalAmount(params);
        double rechargeTotalAmount = oConvertUtils.getDouble(map.get("amount")+"",0.00);
        //可退款金额
        double refundableAmount = 0.00;
        if(rechargeTotalAmount > 0){
            //开票金额（开票中+开票成功）
            params.put("status","");
            params.put("inStatus","0,1,2,7");
            double billAmount = iCaishuiBillService.queryBillTotal(params);
            //退款金额（退款中+退款成功）
            params.put("status","");
            params.put("inStatus","0,1,3,4");
            map = iCaishuiRefundRecordService.queryRefundTotal(params);
            double refundAmount = oConvertUtils.getDouble(map.get("money")+"",0.00);
            //可退款金额 = 充值总额 - 开票金额（开票中+开票成功） - 退款金额（退款中+退款成功）
            refundableAmount = BigDecimal.valueOf(rechargeTotalAmount).subtract(BigDecimal.valueOf(billAmount)).subtract(BigDecimal.valueOf(refundAmount)).setScale(BigDecimal.ROUND_HALF_UP).doubleValue();
            if (refundableAmount < 0) refundableAmount = 0.00;
            if (refundableAmount > accountBalance) refundableAmount = accountBalance;//如果可退款金额>账户余额，则只能退款当前可用余额
        }
        if (caishuiRefundRecord.getMoney() > refundableAmount) return Result.error("退款金额不足！");

        //商户信息
        CaishuiBusiness business = iCaishuiBusinessService.getById(loginUser.getCurBusiness());
        if (oConvertUtils.isEmpty(business)) return Result.error("商户信息错误！");

        //添加退款信息
        caishuiRefundRecord.setBusinessId(loginUser.getCurBusiness());
        caishuiRefundRecord.setCompanyId(loginUser.getCurCompany());
        caishuiRefundRecord.setUserId(business.getUserId());
        caishuiRefundRecord.setChannelBusinessId(business.getChannelBusinessId());
        caishuiRefundRecord.setYurRef(FillRuleUtil.OrderNumberRule("TK",""));
        caishuiRefundRecord.setServiceFee(fee);
        caishuiRefundRecord.setRemark("退款");
        caishuiRefundRecord.setStatus(0);
        caishuiRefundRecord.setInitiate(1);
        iCaishuiRefundRecordService.save(caishuiRefundRecord);
        return Result.OK("添加成功！");
    }

    /**
     * 提交、撤销
     *
     * @param id
     * @param status
     * @return
     */
    @AutoLog(value = "退款记录[B端]-提交、撤销", terminal = 2)
    @ApiOperation(value = "退款记录[B端]-提交、撤销", notes = "退款记录[B端]-提交、撤销")
    @GetMapping(value = "/statusOne")
    @LimitSubmit(key = "business:refund:statusOne:%bId:%cId", spelKey = "#id")
    public Result<?> statusOne(@RequestParam(name = "id", required = true) String id,
                               @RequestParam(name = "captcha", required = false) String captcha,
                               @RequestParam(name = "status", required = true) int status) {
        //当前登录用户
        LoginUser loginUser = TokenUtils.getLoginUser();
        CaishuiRefundRecord refundRecord = iCaishuiRefundRecordService.getById(id);
        if(oConvertUtils.isEmpty(refundRecord)){
            return Result.error("退款信息错误！");
        }
        if (status == 1) { //提交
            //从缓存中获取手机验证码
            Object code = redisUtil.get(CommonConstant.PHONE_REDIS_KEY_PRE + loginUser.getUsername());
            if (oConvertUtils.isEmpty(code)) {
                return Result.error("短信验证码已失效！");
            } else if (!captcha.equals(code)) {
                return Result.error("短信验证码错误！");
            }
            if(refundRecord.getStatus() != 0){
                return Result.error("退款信息错误！");
            }
        }else if (status == -1){//撤销
            if(refundRecord.getStatus() != 0 && refundRecord.getStatus() != 1){
                return Result.error("退款信息错误！");
            }
        }
        refundRecord.setStatus(status);
        refundRecord.setSubmitTime(new Date());
        iCaishuiRefundRecordService.updateById(refundRecord);
        return Result.OK("提交成功!");
    }

    /**
     * 导出excel
     *
     * @param request
     * @param caishuiRefundRecord
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, CaishuiRefundRecord caishuiRefundRecord) {
        caishuiRefundRecord.setBusinessId(TokenUtils.getLoginUser().getCurBusiness());
        caishuiRefundRecord.setCompanyId(TokenUtils.getLoginUser().getCurCompany());
        return super.exportXls(request, caishuiRefundRecord, CaishuiRefundRecord.class, "退款记录[B端]");
    }

}
